package com.example.teesystem.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.teesystem.common.utils.Response;
import com.example.teesystem.common.utils.ResultCode;
import com.example.teesystem.entity.Boat;
import com.example.teesystem.entity.BoatRank;
import com.example.teesystem.entity.Issue;
import com.example.teesystem.entity.vo.boatGame.*;
import com.example.teesystem.entityDto.IssueSimpleMessage;
import com.example.teesystem.filter.MyHandlerInterceptor;
import com.example.teesystem.mapper.BoatRankMapper;
import com.example.teesystem.mapper.IssueMapper;
import com.example.teesystem.service.BoatService;
import com.example.teesystem.mapper.BoatMapper;
import lombok.RequiredArgsConstructor;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Service;

import java.util.*;

/**
* @author 12510
* @description 针对表【t_boat】的数据库操作Service实现
* @createDate 2022-11-26 12:46:51
*/
@Service
@RequiredArgsConstructor
public class BoatServiceImpl extends ServiceImpl<BoatMapper, Boat>
    implements BoatService{

    private final BoatMapper boatMapper;
    private final IssueMapper issueMapper;
    private final BoatRankMapper boatRankMapper;

    @Override
    public synchronized Response boatSearch(BoatSearch boatSearch) {
        //未分配房间
        if(boatSearch.getRoomId()==null||boatSearch.getRoomId().equals("")){
            Boat boat = boatMapper.getBoatByUid(MyHandlerInterceptor.getUid(),boatSearch.getCourseId());
            if(boat!=null){
                boatMapper.deleteById(boat);
            }
            List<BoatRoom> boatRoom = boatMapper.getBoatRoom(boatSearch.getCourseId());
            int i = 0;
            for(;i<boatRoom.size();i++){
                if(boatRoom.get(i).getNum()<3){
                    Boat boat1 = new Boat();
                    boat1.setRoomId(boatRoom.get(i).getRoomId());
                    boat1.setUid(MyHandlerInterceptor.getUid());
                    boat1.setCourseId(boatSearch.getCourseId());
                    boatMapper.insert(boat1);
                    boatRoom.get(i).setNum(boatRoom.get(i).getNum()+1);
                    //达到3个人
                    if(boatRoom.get(i).getNum()==3){
                        List<Boat> boats = boatMapper.getBoatByRoomId(boat1.getRoomId());
                        List<BoatPlayer> boatPlayers = new ArrayList<>();
                        for (Boat value : boats) {
                            boatPlayers.add(new BoatPlayer(value));
                        }
                        List<Issue> issues = issueMapper.getBoatGameIssue(boatSearch.getCourseId());
                        return Response.ok(new SearchResponse(boatPlayers,issues));
                    }
                    Map<String,String> map = new HashMap<>();
                    map.put("roomId",boat1.getRoomId());
                    return Response.error(ResultCode.WAITING,map);
                }
            }
            //没有合适房间，新建房间
            if(i == boatRoom.size()){
                String roomId = UUID.randomUUID().toString();
                Boat boat1 = new Boat();
                boat1.setUid(MyHandlerInterceptor.getUid());
                boat1.setRoomId(roomId);
                boat1.setCourseId(boatSearch.getCourseId());
                boatMapper.insert(boat1);
                Map<String,String> map = new HashMap<>();
                map.put("roomId",roomId);
                return Response.error(ResultCode.WAITING,map);
            }
        }//已有房间
        else {
            List<Boat> boats = boatMapper.getBoatByRoomId(boatSearch.getRoomId());
            if(boats.size() == 3){
                List<BoatPlayer> boatPlayers = new ArrayList<>();
                for (Boat boat : boats) {
                    boatPlayers.add(new BoatPlayer(boat));
                }
                List<Issue> issues = issueMapper.getBoatGameIssue(boatSearch.getCourseId());
                return Response.ok(new SearchResponse(boatPlayers,issues));
            }else {
                Map<String,String> map = new HashMap<>();
                map.put("roomId",boatSearch.getRoomId());
                return Response.error(ResultCode.WAITING,map);
            }
        }
        return Response.error(ResultCode.SEARCH_FAIL);
    }

    @Override
    public synchronized Response check(BoatCheck boatCheck) {
        List<Boat> boatsFinish = boatMapper.getFinishPlayer(boatCheck.getRoomId());
        boatMapper.updatePlayer(boatCheck.getScore(), MyHandlerInterceptor.getUid(),boatCheck.getRoomId(),boatCheck.getTotalNum(),boatCheck.getRightNum());
        if(boatsFinish!=null&&boatsFinish.size()!=0){
            return Response.error(ResultCode.GAME_OVER);
        }
        List<Boat> boats = boatMapper.getBoatByRoomId(boatCheck.getRoomId());
        List<BoatPlayer> boatPlayers = new ArrayList<>();
        for (Boat value : boats) {
            boatPlayers.add(new BoatPlayer(value));
        }
        return Response.ok(boatPlayers);
    }

    @Override
    public synchronized Response end(BoatCheck boatCheck) {
        boatMapper.updateFinish(boatCheck.getScore(),MyHandlerInterceptor.getUid(),boatCheck.getRoomId(),boatCheck.getTotalNum(),boatCheck.getRightNum());
        boatMapper.updateRoomFinish(boatCheck.getRoomId());
        List<Boat> boats = boatMapper.getBoatByRoomId(boatCheck.getRoomId());
        boolean isWin = true;
        List<BoatPlayer> boatPlayers = new ArrayList<>();
        for (Boat value : boats) {
            if(!value.getUid().equals(MyHandlerInterceptor.getUid()) && value.getScore()>boatCheck.getScore()){
                isWin = false;
            }
            boatPlayers.add(new BoatPlayer(value));
        }
        BoatRank boatRank = boatRankMapper.getBoatRankByCourseId(MyHandlerInterceptor.getUid(), boatCheck.getCourseId());
        if(boatRank == null){
            BoatRank myBoatRank = new BoatRank();
            myBoatRank.setUid(MyHandlerInterceptor.getUid());
            myBoatRank.setScore(Math.max(boatCheck.getScore(),0));
            myBoatRank.setCourseId(boatCheck.getCourseId());
            if(isWin){
                myBoatRank.setWinNum(1);
            }else {
                myBoatRank.setWinNum(0);
            }
            boatRankMapper.insert(myBoatRank);
        }else {
            if(isWin){
                boatRank.setWinNum(boatRank.getWinNum()+1);
            }
            boatRank.setScore(Math.max(0,boatRank.getScore()+boatCheck.getScore()));
            boatRankMapper.updateById(boatRank.getId(),boatRank.getWinNum(),boatRank.getScore(),new Date());
        }
        return Response.ok(boatPlayers);
    }
}




